package state.bean;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Vector;

import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;

public class File {
  public static final int READ = Connector.READ;
  
  public static final int WRITE = Connector.WRITE;
  
  public static final int READ_WRITE = Connector.READ_WRITE;
  
  private final static String ROOT_PATH = "file:///";
  
  private static Vector allFile = new Vector();
  
  private String path;
  
  private String name;
  
  private File[] childs;
  
  private FileConnection fc;
  
  private int mode = READ;
  
  private boolean isDirectory = false;
  
  private boolean isHidden = false;
  
  private long lastModified = -1;
  
  private long fileSize = -1;
  
  private long availableSize = -1;
  
  private File parent;
  
  private File(String path, int mode) {
    setPath(path);
    this.mode = mode;
  }
  
  public static File getFile(String path, int mode) throws IOException {
    File file = new File(path, mode);
    allFile.addElement(file);
    return file;
  }
  
  public static File getRoot(int mode) throws IOException {
    return getFile(ROOT_PATH, mode);
  }
  
  private FileConnection getConnector() throws IOException {
    if (fc == null) {
      fc = (FileConnection) Connector.open(path, mode);
      isDirectory = fc.isDirectory();
      isHidden = fc.isHidden();
      lastModified = fc.lastModified();
    }
    return fc;
  }
  
  public void delete() throws IOException {
    getConnector(READ_WRITE).delete();
  }
  
  public long lastModified() throws IOException {
    if (lastModified == -1) {
      lastModified = getConnector().lastModified();
    }
    return lastModified;
  }
  
  public String getName() {
    return name;
  }
  
  public File getParent() throws IOException {
    if (parent == null && !path.equals(ROOT_PATH)) {
      int index = path.lastIndexOf('/');
      if (index > -1) {
        parent = getFile(path.substring(0, index), mode);
      }
    }
    return parent;
  }

  public void rename(String name) throws IOException {
    fc = getConnector(READ_WRITE);
    fc.rename(name);
    setPath(fc.getPath());
  }
  
  public long fileSize() throws IOException {
    if (fileSize == -1) {
      fileSize = getConnector().fileSize(); 
    }
    return fileSize;
  }
  
  public long availableSize() throws IOException {
    if (availableSize == -1) {
      availableSize = getConnector().availableSize(); 
    }
    return availableSize;
  }
  
  public boolean isDirectory() {
    if (fc == null) {
      isDirectory = path.charAt(path.length() - 1) == '/';
    }
    return isDirectory;
  }

  public boolean isHidden() {
    return isHidden;
  }

  private FileConnection getConnector(int mode) throws IOException {
    if (mode != this.mode) {
      this.mode = mode;
      detroyConnector();
    }
    return getConnector();
  }
  
  public File[] list() throws IOException {
    if (childs != null) {
      return childs;
    }

    fc = getConnector();
    Enumeration em = fc.list();
    Vector files = new Vector();
    while (em.hasMoreElements()) {
      String fileName = em.nextElement().toString();
      String filePath = path + fileName;
      File file = getFile(filePath, mode);
      file.parent = this;
      files.addElement(file);
    }
    
    childs = new File[files.size()];
    for (int i = 0; i < files.size(); i++) {
      childs[i] = (File) files.elementAt(i);
    }
    return childs;
  }
  
  public void refresh() {
    childs = null;
    detroyConnector();
  }
  
  private void setPath(String path) {
    this.path = path;
    if (path.equals(ROOT_PATH)) {
      name = "Root";
    } else {
      if (isDirectory()) {
        int index = path.lastIndexOf('/');
        index = path.substring(0, index).lastIndexOf('/');
        if (index > -1) {
          name = path.substring(index + 1);
        } else {
          name = path;
        }
      } else {
        int index = path.lastIndexOf('/');
        if (index > -1) {
          name = path.substring(index + 1);
        } else {
          name = path;
        }
      }
    }
  }
  
  public String getPath() {
    return path;
  }

  private void detroyConnector() {
    if (fc != null) {
      try {
        fc.close();
        fc = null;
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
  
  public static void detroyAll() {
    for (int i = 0; i < allFile.size(); i++) {
      ((File) allFile.elementAt(i)).detroyConnector();
    }
    allFile.removeAllElements();
  }
}
